#ifndef _ACENGINE_H
#define _ACENGINE_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>

/* byte definition */
typedef unsigned char AceByte;

#define ACE_BYTE_MIN (0x0)
#define ACE_BYTE_MAX (0x100)

/* status */
enum _AceStatus
{
	ACE_SUCCESS,
	ACE_BAD_ALLOC,
	ACE_ALREADY_EXIST,
	ACE_NOT_FOUND,
};

typedef enum _AceStatus AceStatus;

#define ACE_SUCCESS(status) \
	((status) == ACE_SUCCESS)

/* action */
enum _AceAction
{
	ACE_CONTINUE,
	ACE_STOP,
};

typedef enum _AceAction AceAction;

/* memory allocation */
typedef void * AceAlloc(void *context, size_t size);
typedef void AceFree(void *context, void *ptr);

/* callback */
typedef AceAction AceMatchCallback(void *context, size_t offset, void *key);

/* structures */
struct __AceTrieNode;
typedef struct __AceTrieNode _AceTrieNode;

struct __AceTNAllocator;
typedef struct __AceTNAllocator _AceTNAllocator;

struct _AceAllocator;
typedef struct _AceAllocator AceAllocator;

struct _AceContext;
typedef struct _AceContext AceContext;

struct _AceAllocator
{
	void *context;
	AceAlloc *alloc_func;
	AceFree *free_func;
};

struct _AceContext
{
	AceAllocator allocator;
	_AceTNAllocator *tnallocator;
	_AceTrieNode *root;
	_AceTrieNode *current;
	size_t offset;
};

/* constructor */
extern AceStatus ace_initialize(AceContext *thiz,
	AceAlloc *alloc_func, AceFree *free_func, void *alloc_context);

/* destructor */
extern void ace_finalize(AceContext *thiz);

/* insert pattern */
extern AceStatus ace_insert_pattern(AceContext *thiz,
	AceByte *pattern, size_t size, void *key);

/* retrieve key */
extern AceStatus ace_retrieve_key(AceContext *thiz,
	AceByte *pattern, size_t size, void **key);

/* build ac automation */
extern AceStatus ace_build_automation(AceContext *thiz);

/* append text */
extern AceAction ace_append_text(AceContext *thiz, AceByte *buffer, size_t size,
	AceMatchCallback *callback, void *context);

/* reset */
extern void ace_reset(AceContext *thiz);

#ifdef __cplusplus
}
#endif

#endif
